---
title: "Developer API"
description: "Access your Omi data programmatically with the Developer API. Build custom integrations, analytics dashboards, and automation workflows using your memories, conversations, and action items."
---

## Overview

The Omi Developer API provides programmatic access to your personal Omi data, allowing you to build custom applications and integrations. Use it to create analytics dashboards, export data to other services, build automation workflows, or contribute data back to your Omi account.

## Getting Started

### 1. Generate an API Key

1. Open the Omi app
2. Navigate to `Settings > Developer`
3. Under the "Developer API Keys" section, click "Create Key"
4. Give your key a descriptive name (e.g., "My Analytics Dashboard")
5. Copy the key immediately - you won't be able to see it again!

### 2. Making API Requests

All API requests must include your API key in the `Authorization` header:

```bash
curl -H "Authorization: Bearer omi_dev_your_api_key_here" \
  https://api.omi.me/v1/dev/user/memories
```

## Base URL

```
https://api.omi.me/v1/dev
```

For self-hosted instances, replace with your backend URL.

## Quick Reference

| Resource | Method | Endpoint | Description |
|----------|--------|----------|-------------|
| **API Keys** | GET | `/v1/dev/keys` | List all API keys |
| | POST | `/v1/dev/keys` | Create new API key |
| | DELETE | `/v1/dev/keys/{key_id}` | Revoke API key |
| **Memories** | GET | `/v1/dev/user/memories` | Get memories |
| | POST | `/v1/dev/user/memories` | Create memory |
| | POST | `/v1/dev/user/memories/batch` | Create multiple memories |
| **Action Items** | GET | `/v1/dev/user/action-items` | Get action items |
| | POST | `/v1/dev/user/action-items` | Create action item |
| | POST | `/v1/dev/user/action-items/batch` | Create multiple action items |
| **Conversations** | GET | `/v1/dev/user/conversations` | Get conversations |
| | POST | `/v1/dev/user/conversations` | Create from text |
| | POST | `/v1/dev/user/conversations/from-segments` | Create from transcript |

## Endpoints

### Key Management

#### List API Keys

```http
GET /v1/dev/keys
```

Retrieve all your developer API keys (excluding the secret values).

**Response:**

```json
[
  {
    "id": "key_123abc",
    "name": "My Analytics Dashboard",
    "key_prefix": "omi_dev_abc123",
    "created_at": "2025-01-15T10:30:00Z",
    "last_used_at": "2025-01-20T14:22:00Z"
  }
]
```

#### Create API Key

```http
POST /v1/dev/keys
```

Create a new developer API key.

**Request Body:**

```json
{
  "name": "My New Integration"
}
```

**Response:**

```json
{
  "id": "key_456def",
  "name": "My New Integration",
  "key_prefix": "omi_dev_def456",
  "key": "omi_dev_def456_full_secret_key_here",
  "created_at": "2025-01-20T15:00:00Z",
  "last_used_at": null
}
```

<Warning>
The full API key is only returned once during creation. Store it securely!
</Warning>

#### Revoke API Key

```http
DELETE /v1/dev/keys/{key_id}
```

Revoke a specific API key. This action cannot be undone.

**Response:** `204 No Content`

---

### User Data

All user data endpoints require authentication via your Developer API key.

#### Memories

##### Get Memories

```http
GET /v1/dev/user/memories
```

Retrieve your memories with optional filtering.

**Query Parameters:**

- `limit` (integer, optional): Maximum number of memories to return. Default: 25
- `offset` (integer, optional): Number of memories to skip. Default: 0
- `categories` (string, optional): Comma-separated list of categories to filter by (e.g., "personal,work")

**Example Request:**

```bash
curl -H "Authorization: Bearer omi_dev_your_api_key" \
  "https://api.omi.me/v1/dev/user/memories?limit=50&offset=0&categories=personal,work"
```

**Response:**

```json
[
  {
    "id": "mem_789ghi",
    "content": "Discussed project roadmap for Q1 with team members...",
    "category": "interesting"
  },
  {
    "id": "mem_456def",
    "content": "Reminder to call mom on her birthday next week",
    "category": "system"
  }
]
```

##### Create Memory

```http
POST /v1/dev/user/memories
```

Create a new memory. If no category is provided, memories default to `manual` category and are automatically categorized between `interesting` and `system`.

**Request Body:**

```json
{
  "content": "User prefers dark mode in all applications",
  "category": "system",
  "visibility": "private",
  "tags": ["preferences", "ui"]
}
```

**Parameters:**
- `content` (string, required): The memory content (1-500 characters)
- `category` (string, optional): Memory category - `interesting`, `system`, or `manual` (defaults to `manual` and auto-categorizes to `interesting` or `system` if not provided)
- `visibility` (string, optional): `public` or `private` (default: `private`)
- `tags` (array, optional): List of tags

**Response:**

```json
{
  "id": "mem_xyz789",
  "content": "User prefers dark mode in all applications",
  "category": "system",
  "visibility": "private",
  "tags": ["preferences", "ui"],
  "created_at": "2025-12-06T10:35:00Z",
  "updated_at": "2025-12-06T10:35:00Z",
  "manually_added": true,
  "scoring": "01_999_1733482500"
}
```

##### Create Memories (Batch)

```http
POST /v1/dev/user/memories/batch
```

Create multiple memories in a single request (max 25).

**Request Body:**

```json
{
  "memories": [
    {
      "content": "Meeting scheduled with team next Monday",
      "category": "system"
    },
    {
      "content": "Discovered new productivity technique",
      "visibility": "public"
    }
  ]
}
```

**Response:**

```json
{
  "memories": [
    { "id": "mem_001", "content": "...", ... },
    { "id": "mem_002", "content": "...", ... }
  ],
  "created_count": 2
}
```

#### Action Items

##### Get Action Items

```http
GET /v1/dev/user/action-items
```

Retrieve all your action items with optional filtering.

**Query Parameters:**

- `conversation_id` (string, optional): Filter by conversation ID (use "null" for standalone items)
- `completed` (boolean, optional): Filter by completion status
- `start_date` (datetime, optional): Filter by start date (inclusive)
- `end_date` (datetime, optional): Filter by end date (inclusive)
- `limit` (integer, optional): Maximum number to return. Default: 100
- `offset` (integer, optional): Number of items to skip. Default: 0

**Example Request:**

```bash
curl -H "Authorization: Bearer omi_dev_your_api_key" \
  "https://api.omi.me/v1/dev/user/action-items?completed=false&limit=50"
```

**Response:**

```json
[
  {
    "id": "action_101",
    "description": "Review budget proposal",
    "completed": false,
    "created_at": "2025-01-20T10:15:00Z",
    "updated_at": "2025-01-20T10:15:00Z",
    "due_at": null,
    "completed_at": null,
    "conversation_id": "conv_202"
  },
  {
    "id": "action_102",
    "description": "Call dentist for appointment",
    "completed": true,
    "created_at": "2025-01-19T14:00:00Z",
    "updated_at": "2025-01-20T09:00:00Z",
    "due_at": "2025-01-25T00:00:00Z",
    "completed_at": "2025-01-20T09:00:00Z",
    "conversation_id": null
  }
]
```

##### Create Action Item

```http
POST /v1/dev/user/action-items
```

Create a new action item (task/to-do).

**Request Body:**

```json
{
  "description": "Review pull request #123",
  "completed": false,
  "due_at": "2025-12-08T15:00:00+00:00"
}
```

**Parameters:**
- `description` (string, required): The action item description (1-500 characters)
- `completed` (boolean, optional): Whether completed (default: `false`)
- `due_at` (datetime, optional): Due date in ISO 8601 format with timezone

**Response:**

```json
{
  "id": "action_abc123",
  "description": "Review pull request #123",
  "completed": false,
  "created_at": "2025-12-06T10:30:00Z",
  "updated_at": "2025-12-06T10:30:00Z",
  "due_at": "2025-12-08T15:00:00+00:00",
  "completed_at": null,
  "conversation_id": null
}
```

<Note>
FCM notifications are automatically sent if a `due_at` date is provided.
</Note>

##### Create Action Items (Batch)

```http
POST /v1/dev/user/action-items/batch
```

Create multiple action items in a single request (max 50).

**Request Body:**

```json
{
  "action_items": [
    {
      "description": "Task 1",
      "due_at": "2025-12-08T15:00:00+00:00"
    },
    {
      "description": "Task 2",
      "completed": false
    }
  ]
}
```

**Response:**

```json
{
  "action_items": [
    { "id": "action_001", "description": "Task 1", ... },
    { "id": "action_002", "description": "Task 2", ... }
  ],
  "created_count": 2
}
```

#### Conversations

##### Get Conversations

```http
GET /v1/dev/user/conversations
```

Retrieve your conversation transcripts. Only completed, non-discarded conversations are returned.

**Query Parameters:**

- `limit` (integer, optional): Maximum number to return. Default: 25
- `offset` (integer, optional): Number to skip. Default: 0
- `start_date` (datetime, optional): Filter by start date (inclusive)
- `end_date` (datetime, optional): Filter by end date (inclusive)
- `categories` (string, optional): Comma-separated list of categories (e.g., "personal,business")
- `include_transcript` (boolean, optional): Include full transcript segments. Default: false

**Example Request:**

```bash
curl -H "Authorization: Bearer omi_dev_your_api_key" \
  "https://api.omi.me/v1/dev/user/conversations?limit=10&include_transcript=true"
```

**Response (without transcript):**

```json
[
  {
    "id": "conv_202",
    "created_at": "2025-01-20T13:50:00Z",
    "started_at": "2025-01-20T13:50:00Z",
    "finished_at": "2025-01-20T14:10:00Z",
    "language": "en",
    "source": "omi",
    "structured": {
      "title": "Feature Discussion",
      "overview": "Brainstorming session for new features",
      "emoji": "💼",
      "category": "business",
      "action_items": [
        {
          "description": "Create mockups for new UI",
          "completed": false,
          "created_at": "2025-01-20T14:10:00Z",
          "updated_at": "2025-01-20T14:10:00Z",
          "due_at": null,
          "completed_at": null
        }
      ],
      "events": []
    }
  }
]
```

**Response (with transcript):**

```json
[
  {
    "id": "conv_202",
    "created_at": "2025-01-20T13:50:00Z",
    "started_at": "2025-01-20T13:50:00Z",
    "finished_at": "2025-01-20T14:10:00Z",
    "language": "en",
    "source": "friend",
    "structured": {
      "title": "Feature Discussion",
      "overview": "Brainstorming session for new features",
      "emoji": "💼",
      "category": "business",
      "action_items": [
        {
          "description": "Create mockups for new UI",
          "completed": false,
          "created_at": "2025-01-20T14:10:00Z",
          "updated_at": "2025-01-20T14:10:00Z",
          "due_at": null,
          "completed_at": null
        }
      ],
      "events": []
    },
    "transcript_segments": [
      {
        "id": "seg_001",
        "text": "Let's discuss the new feature",
        "speaker_id": 0,
        "start": 0.0,
        "end": 2.5
      },
      {
        "id": "seg_002",
        "text": "I think we should focus on the user interface first",
        "speaker_id": 1,
        "start": 2.5,
        "end": 5.8
      }
    ]
  }
]
```

##### Create Conversation from Text

```http
POST /v1/dev/user/conversations
```

Create a new conversation from text. The text is processed through the full conversation pipeline to extract structured data, action items, and memories.

**Request Body:**

```json
{
  "text": "We discussed the upcoming product launch. Sarah mentioned we need to finalize the marketing materials by next Wednesday. I committed to reviewing the design mockups by Monday.",
  "text_source": "other_text",
  "text_source_spec": "slack_discussion",
  "started_at": "2025-12-06T14:00:00+00:00",
  "finished_at": "2025-12-06T14:30:00+00:00",
  "language": "en"
}
```

**Parameters:**
- `text` (string, required): The conversation text/transcript (1-100,000 characters)
- `text_source` (string, optional): Source type - `audio_transcript`, `message`, or `other_text` (default: `other_text`)
- `text_source_spec` (string, optional): Additional source info (e.g., 'email', 'slack', 'whatsapp')
- `started_at` (datetime, optional): When conversation started (defaults to now)
- `finished_at` (datetime, optional): When conversation finished (defaults to `started_at` + 5 minutes)
- `language` (string, optional): Language code (default: 'en')
- `geolocation` (object, optional): Geolocation data

**Response:**

```json
{
  "id": "conv_456",
  "status": "completed",
  "discarded": false
}
```

**Processing Pipeline:**

When you create a conversation, the following happens automatically:
- **Discard Detection**: Determines if content is meaningful enough to save
- **Structured Generation**: Creates title, overview, category, and emoji
- **Action Item Extraction**: Identifies and creates action items (with deduplication against past 2 days)
- **Memory Extraction**: Extracts interesting facts and insights (up to 4 per conversation)
- **App Integration**: Triggers enabled summarization apps
- **Webhooks**: Notifies external systems

<Note>
Memories and action items are extracted asynchronously. Use the GET endpoints to retrieve them after creation.
</Note>

##### Create Conversation from Transcript Segments

```http
POST /v1/dev/user/conversations/from-segments
```

Create a conversation from structured transcript segments with speaker diarization and timing information.

**Request Body:**

```json
{
  "transcript_segments": [
    {
      "text": "Hey, how are you doing?",
      "speaker": "SPEAKER_00",
      "is_user": true,
      "start": 0.0,
      "end": 2.5
    },
    {
      "text": "I'm doing great, thanks for asking!",
      "speaker": "SPEAKER_01",
      "is_user": false,
      "start": 2.8,
      "end": 5.2
    }
  ],
  "source": "phone",
  "language": "en"
}
```

**Parameters:**
- `transcript_segments` (array, required): List of transcript segments (1-500 segments)
  - `text` (string, required): The spoken text
  - `speaker` (string, optional): Speaker identifier like 'SPEAKER_00', 'SPEAKER_01' (default: 'SPEAKER_00')
  - `speaker_id` (integer, optional): Numeric speaker ID (auto-calculated if not provided)
  - `is_user` (boolean, optional): Whether this segment is from the user (default: `false`)
  - `person_id` (string, optional): ID of known person speaking
  - `start` (float, required): Start time in seconds (e.g., 0.0, 1.5, 60.2)
  - `end` (float, required): End time in seconds (e.g., 1.5, 3.0, 65.8)
- `source` (string, optional): Source of conversation (default: `external_integration`)
  - Available: `omi`, `friend`, `openglass`, `phone`, `desktop`, `apple_watch`, `bee`, `plaud`, `frame`, `screenpipe`, `workflow`, `sdcard`, `external_integration`
- `started_at` (datetime, optional): When conversation started (defaults to now)
- `finished_at` (datetime, optional): When conversation finished (calculated from last segment if not provided)
- `language` (string, optional): Language code (default: 'en')
- `geolocation` (object, optional): Geolocation data

**Response:**

```json
{
  "id": "conv_789",
  "status": "completed",
  "discarded": false
}
```

<Note>
Unlike text-based conversations, transcript segments ARE stored in the `transcript_segments` field and can be retrieved with `include_transcript=true`.
</Note>

## Authentication

All API requests (except key creation) require authentication using your Developer API key:

```http
Authorization: Bearer omi_dev_your_api_key_here
```

## Rate Limits

- **Rate Limit:** 100 requests per minute per API key
- **Daily Limit:** 10,000 requests per day per user

Rate limit headers are included in responses:

```http
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1642694400
```

## Error Responses

The API uses standard HTTP status codes:

- `200 OK` - Request succeeded
- `204 No Content` - Request succeeded with no response body
- `400 Bad Request` - Invalid request parameters
- `401 Unauthorized` - Invalid or missing API key
- `403 Forbidden` - API key doesn't have required permissions
- `404 Not Found` - Resource not found
- `429 Too Many Requests` - Rate limit exceeded
- `500 Internal Server Error` - Server error

**Error Response Format:**

```json
{
  "error": {
    "message": "Invalid API key",
    "code": "invalid_api_key"
  }
}
```

## Security Best Practices

<Warning>
Never commit API keys to version control or share them publicly!
</Warning>

1. **Store keys securely**: Use environment variables or secret management services
2. **Rotate keys regularly**: Generate new keys and revoke old ones periodically
3. **Use specific keys**: Create separate keys for different applications
4. **Monitor usage**: Check the "last used" timestamp in your key list
5. **Revoke immediately**: If a key is compromised, revoke it right away

## Example Use Cases

### Import Data from Other Services

Import your tasks from another task management system:

```python
import requests

api_key = "omi_dev_your_api_key"
headers = {"Authorization": f"Bearer {api_key}"}

# Import tasks from your external system
tasks = get_tasks_from_external_system()

action_items = [
    {
        "description": task["title"],
        "due_at": task["due_date"],
        "completed": task["completed"]
    }
    for task in tasks
]

response = requests.post(
    "https://api.omi.me/v1/dev/user/action-items/batch",
    headers=headers,
    json={"action_items": action_items}
)

print(f"Imported {response.json()['created_count']} action items")
```

### Create Memories from Notes

Automatically create memories from your note-taking app:

```javascript
const API_KEY = process.env.OMI_API_KEY;

async function syncNotes(notes) {
  const memories = notes.map(note => ({
    content: note.content,
    category: "system",
    tags: note.tags
  }));

  const response = await fetch(
    'https://api.omi.me/v1/dev/user/memories/batch',
    {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${API_KEY}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ memories })
    }
  );

  const result = await response.json();
  console.log(`Created ${result.created_count} memories`);
}
```

### Process Meeting Transcripts

Upload meeting transcripts with speaker information:

```bash
#!/bin/bash
API_KEY="omi_dev_your_api_key"

curl -X POST "https://api.omi.me/v1/dev/user/conversations/from-segments" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "transcript_segments": [
      {
        "text": "Let'\''s review the quarterly results",
        "speaker": "SPEAKER_00",
        "is_user": true,
        "start": 0.0,
        "end": 3.5
      },
      {
        "text": "Revenue is up 25% from last quarter",
        "speaker": "SPEAKER_01",
        "is_user": false,
        "start": 4.0,
        "end": 7.2
      }
    ],
    "source": "phone",
    "language": "en"
  }'
```

### Analytics Dashboard

Build a custom dashboard to visualize your memory trends:

```python
import requests
import pandas as pd

api_key = "omi_dev_your_api_key"
headers = {"Authorization": f"Bearer {api_key}"}

response = requests.get(
    "https://api.omi.me/v1/dev/user/memories",
    headers=headers,
    params={"limit": 1000}
)

memories = response.json()
df = pd.DataFrame(memories)
# Analyze and visualize your data
```

### Action Item Tracker

Sync your Omi action items with your task management system:

```javascript
const API_KEY = process.env.OMI_API_KEY;

async function syncActionItems() {
  const response = await fetch(
    'https://api.omi.me/v1/dev/user/action-items?completed=false',
    {
      headers: {
        'Authorization': `Bearer ${API_KEY}`
      }
    }
  );

  const actionItems = await response.json();
  // Sync with your task manager
}
```

### Data Export

Export your conversations to a local database:

```bash
#!/bin/bash
API_KEY="omi_dev_your_api_key"

curl -H "Authorization: Bearer $API_KEY" \
  "https://api.omi.me/v1/dev/user/conversations?limit=1000" \
  > conversations_backup.json
```

## Comparison with MCP

| Feature | Developer API | MCP |
|---------|--------------|-----|
| **Purpose** | Direct HTTP API access | AI assistant integration |
| **Access** | Read & write user data | Read/write with AI context |
| **Use Case** | Custom apps, dashboards, automation | Claude Desktop, AI agents |
| **Authentication** | Bearer token | Environment variable |
| **Best For** | Web apps, integrations, batch operations | AI-powered workflows |

Use the **Developer API** when you need:
- Programmatic access to your data for custom applications
- Batch operations (creating multiple memories/action items at once)
- Integration with external services (task managers, note apps, etc.)
- Custom automation workflows

Use **MCP** when you want:
- AI assistants like Claude to interact with your Omi data
- Natural language queries and AI-powered insights
- Context-aware AI assistance

## Support

For questions, issues, or feature requests:

- **Documentation:** https://docs.omi.me
- **GitHub Issues:** https://github.com/BasedHardware/omi/issues
- **Discord:** Join our community at https://discord.gg/omi

## License

The Omi Developer API client libraries and examples are licensed under the MIT License.
